package poidemo.multithread;


import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * @author huanghao
 * @version 1.0
 * @date 2020/1/8 11:48
 */

public class CallableDemoController {

    public static void main(String[] args) {
        long t1 = System.currentTimeMillis();
        List<Map> maps = selectDemoCount();
        System.out.println(maps);
        long t2 = System.currentTimeMillis();
        System.out.println("总耗时：" + (t2 - t1));
    }


    //需求是说异步查询结果 最终汇合所有结果
    private static List<Map> selectDemoCount() {
        ArrayList<Map> maps = new ArrayList<>();
        List<Callable<Integer>> tasks = new ArrayList<>();

        //定义固定长度的线程池  防止线程过多
        ExecutorService execservice = Executors.newFixedThreadPool(4);

        //拼装任务参数
        for (int i = 0; i < 5; i++) {
            CallableQuery callableQuery = new CallableQuery(i);
            tasks.add(callableQuery);
        }

        try {
            //执行多线程任务
            List<Future<Integer>> futures = execservice.invokeAll(tasks);
            if (CollectionUtils.isNotEmpty(futures) && futures.size() > 0) {
                int j = 0;
                for (Future<Integer> future : futures) {
                    HashMap<Integer, Integer> map = new HashMap<>();
                    //其实future.get的时候才会触发返回结果,任务没有完成主线程此处会阻塞直至任务完成
                    map.put(j, future.get());
                    maps.add(map);
                    j++;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            execservice.shutdown();
        }

        return maps;
    }


    static class CallableQuery implements Callable<Integer> {
        //此处可以使用构造方法注入Service or Mapper
        private Integer i;

        CallableQuery(Integer i) {
            this.i = i;
        }

        @Override
        public Integer call() throws Exception {
            System.out.println("现在执行任务" + i);
            Thread.sleep(i * 1000);
            return i;
        }
    }
}
